// file: 格式化的输入输出

#include <stdio.h>

int main(int argc, char const *argv[])
{
    // printf
    // %[flags][width][.prec][hIL]type

    // | Flag | 含义 |
    // | :-: | :-: |
    // | - | 左对齐 |
    // | + | 在前面放 + 或 - |
    // | (space) | 整数留空 |
    // | 0 | 0填充 |
    printf("\nPRINTF-FLAG\n");
    printf("%9d\n", 123);
    printf("%+9d\n", 123);
    printf("%-9d\n", 123);
    // -+ 和 -+ 都可以
    printf("%+-9d\n", 123);
    // + 是强制正数输出 + ，负数正常输出
    printf("%+9d\n", -123);
    // 0填充: 只在左边填，左对齐就不填了
    // 负数的 0 会填在 - 号后
    printf("%-09d\n", 123);
    printf("%09d\n", -123);

    // | width 或 prec |            含义            |
    // | :-----------: | :------------------------: |
    // |    number     |         最小字符数         |
    // |       *       |     下一个参数是字符数     |
    // |    .number    |       小数点后的位数       |
    // |      .*       | 下一个参数是小数点后的位数 |
    // number1.number2: 包括小数点及以后的总长度，不是整数部分长度
    printf("\nPRINTF-WIDTH_OR_PREC\n");
    printf("%9.2f\n", 132.0);
    // 把 * 变成 6 ，也就是 %6d
    // 也可以是变量
    printf("%*d\n", 6, 123);
    printf("%*.*f\n", 9, 3, 123.0);

    // | 类型修饰 |    含义     |
    // | :------: | :---------: |
    // |    hh    |  单个字节   |
    // |    h     |    short    |
    // |    l     |    long     |
    // |    ll    |  long long  |
    // |    L     | long double |
    // 这个，我的如果不强制类型转换，就会输出 12345
    printf("\nPRINTF-hIL\n");
    printf("%hhd\n", (char)12345);

    // |  type  |        用于        |  type  |      用于       |
    // | :----: | :----------------: | :----: | :-------------: |
    // | i 或 d |        int         |   g    |      float      |
    // |   u    |    unsigned int    |   G    |      float      |
    // |   o    |       八进制       | a 或 A | 十六进制浮点数  |
    // |   x    |      十六进制      |   c    |      char       |
    // |   X    | 字母大写的十六进制 |   s    |     字符串      |
    // | f 或 F |      float, 6      |   P    |      指针       |
    // | e 或 E |        指数        |   n    | 读入/写出的个数 |
    printf("\nPRINTF-TYPE\n");
    printf("\n");
    int num;
    // 不知道为什么我的想不通QwQ
    printf("%dabc%n\n", 12345, &num);
    printf("num = %d\n", num);
    

    // scanf
    // %[flag]type

    // | flag |    含义    | flag |     含义     |
    // | :--: | :--------: | :--: | :----------: |
    // |  *   |    跳过    |  l   | long, double |
    // | 数字 | 最大字符数 |  ll  |  long long   |
    // |  hh  |    char    |  L   | long double  |
    // |  h   |   short    |      |              |
    printf("\nSCANF-FLAG\n");
    int test;
    // 会跳过第一个数，接收输入的第二个数
    printf("INPUT1 and INPUT2: Ignore INPUT1\n");
    scanf("%*d%d", &test);
    printf("%d\n", test);

    // | type |             用于             |    type    |      用于      |
    // | :--: | :--------------------------: | :--------: | :------------: |
    // |  d   |             int              | a, e, f, g |     float      |
    // |  i   | 整数，可能为十六进制或八进制 |     c      |      char      |
    // |  u   |         unsigned int         |     s      | 字符串（单词） |
    // |  o   |            八进制            |   [...]    |  所允许的字符  |
    // |  x   |           十六进制           |     P      |      指针      |
    printf("\nSCANF-TYPE\n");
    int test2;
    // 如果在这里输入了十六进制数，输出会是0，并且会跳过下一个scanf
    printf("INPUT1: DEC\n");
    scanf("%d", &test2);
    printf("OUTPUT1\n");
    printf("%d\n", test2);
    printf("INPUT2: Can be DEC or HEX or OCT\n");
    scanf("%i", &test2);
    printf("OUTPUT2\n");
    printf("%i\n", test2);

    // [^.] -> 到 . 之前的所有字符


    // printf 和 scanf 的返回值
    // scanf: 读入的项目数
    // printf: 输出的字符数
    int sret, pret;
    int test3;
    printf("\nRET\n");
    printf("INPUT1: Get the return of SCANF\n");
    sret = scanf("%d", &test3);
    printf("OUTPUT1: Get the return of PRINTF\n");
    pret = printf("%d\n", test3);
    // input: 12345
    // sret = 1, pret = 6(包括\n)
    printf("OUTPUT2: The returns\n");
    printf("sret = %d, pret = %d\n", sret, pret);

    return 0;
}